/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.repository.adaptor;

import com.inspur.edp.cef.api.RefObject;
import com.inspur.edp.cef.api.repository.IRootRepository;
import com.inspur.edp.cef.api.repository.RefColumnInfo;
import com.inspur.edp.cef.api.repository.adaptor.IRepositoryAdaptor;
import com.inspur.edp.cef.api.repository.readerWriter.ICefReader;
import com.inspur.edp.cef.entity.entity.EntityDataPropertyValueUtils;
import com.inspur.edp.cef.entity.entity.ICefData;
import com.inspur.edp.cef.repository.assembler.AssoCondition;
import com.inspur.edp.cef.repository.assembler.AssociationInfo;
import com.inspur.edp.cef.repository.assembler.LogicDeleteInfo;

import java.sql.Clob;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;

public abstract class DataTypeAdapter implements IRepositoryAdaptor {
	protected DataTypeAdapter() {
		initAssociations();
	}
	protected DataTypeAdapter(boolean init) {
		if(init){
			initAssociations();
		}
	}

	public LogicDeleteInfo getLogicDeleteInfo(){
		return new LogicDeleteInfo(false, "");
	}

	public abstract ICefData createInstance(ICefReader reader);

	public abstract String getTableNameByColumns(java.util.HashMap<String, String> columns, String keyColumnName, RefObject<String> keyDbColumnName, java.util.ArrayList<String> tableAlias);

	public abstract String getTableNameByRefColumns(java.util.HashMap<String, RefColumnInfo> columns, String keyColumnName, RefObject<String> keyDbColumnName, java.util.ArrayList<String> tableAlias);

	public abstract Object getPersistenceValue(String colName, ICefData data);

	public abstract Object readProperty(String propertyName, ICefReader reader);

	protected abstract void initAssociations();

	private java.util.ArrayList<AssociationInfo> associationInfos;

	protected java.util.ArrayList<AssociationInfo> getAssociationInfos() {
		if (associationInfos == null)
			associationInfos = new ArrayList<AssociationInfo>();
		return associationInfos;
	}

	protected AssociationInfo getAssociation(String propertyName) {
		for (AssociationInfo item : associationInfos) {
			if (propertyName.equals(item.getSourceColumn())) {
				return item;
			}
		}
		throw new RuntimeException("找不到{propertyName}属性对应的关联信息。");
	}

	/**
	 * 添加关联信息
	 *
	 * @param nodeCode      关联节点编号
	 * @param sourceColumn  源字段
	 * @param targetColumn  目标字段
	 * @param refRepository 引用实体Repository
	 * @param refColumns    引用字段集合
	 */
	protected final void addAssociationInfo(String nodeCode, String sourceColumn, String targetColumn, IRootRepository refRepository, java.util.HashMap<String, String> refColumns, String configId) {
		AssociationInfo tempVar = new AssociationInfo();
		tempVar.setNodeCode(nodeCode);
		tempVar.setSourceColumn(sourceColumn);
		tempVar.setTargetColumn(targetColumn);
		tempVar.setRefRepository(refRepository);
		tempVar.setRefColumns(refColumns);
		tempVar.setConfigId(configId);
		AssociationInfo info = tempVar;
		getAssociationInfos().add(info);
	}

	protected final void addAssociationInfo(String nodeCode, String sourceColumn, String targetColumn, IRootRepository refRepository, java.util.HashMap<String, String> refColumns, String configId, String where, ArrayList<AssoCondition> assoConditions) {
		AssociationInfo tempVar = new AssociationInfo();
		tempVar.setNodeCode(nodeCode);
		tempVar.setSourceColumn(sourceColumn);
		tempVar.setTargetColumn(targetColumn);
		tempVar.setRefRepository(refRepository);
		tempVar.setRefColumns(refColumns);
		tempVar.setConfigId(configId);
		tempVar.setWhere(where);
		tempVar.setAssoConditions(assoConditions);
		AssociationInfo info = tempVar;
		getAssociationInfos().add(info);
	}

	protected java.util.HashMap<String, java.util.HashMap<String, String>> AssoMapping = new java.util.HashMap<String, java.util.HashMap<String, String>>();


	protected final void mergeAssoMapper(String propName, java.util.HashMap<String, String> assoMapper) {
		if (!AssoMapping.containsKey(propName)) {
			return;
		}
		for (Map.Entry<String, String> mapperItem : AssoMapping.get(propName).entrySet()) {
			if (!assoMapper.containsKey(mapperItem.getKey())) {
				assoMapper.put(mapperItem.getKey(), mapperItem.getValue());
			}
		}
	}

    protected boolean getBoolean(String value){
        switch (value){
            case "0":
                return false;
            case "1":
                return true;
            default:
                throw new RuntimeException("不正确的布尔值："+value);
        }
    }
	protected String getClobValue(Object obj)
	{
		if(obj instanceof String )
		{
			return obj.toString();
		}
		else {
			try {
				return obj == null ? EntityDataPropertyValueUtils.getStringPropertyDefaultValue() : ((Clob) obj).getSubString(1L, (int) ((Clob) obj).length());
			} catch (SQLException e) {
				throw new RuntimeException("解析备注类型数据：" + obj + "失败");
			}
		}
	}
}
